package tt.dz.order.schedulingjob;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import tt.dz.order.pojo.OrderAccountingStatus;
import tt.dz.order.pojo.OrderInfo;
import tt.dz.order.pojo.OrderRefundStatus;
import tt.dz.order.pojo.WeiXinPayCallBackRecord;
import tt.dz.order.pojo.WeiXinRefundReturnRecord;
import tt.dz.order.util.AmountUtil;
import tt.dz.order.util.OrderConstant.OrderPayChannelCode;
import tt.dz.order.util.OrderConstant.OrderStatus;
import tt.dz.order.util.UUIDUtil;
import tt.dz.order.util.WeiXinPayUtil;
import tt.dz.order.util.XmlUtil;

/**
 * @Title 向微信支付平台发送充电预约退款请求的job
 * @author zhoutian   
 * @date 2015-11-17
 */
@Component
public class SendRefundingRequestToWeiXinJob extends QuartzJobBean {
	private static Logger log = LoggerFactory.getLogger(SendRefundingRequestToWeiXinJob.class);
	
	//截取的大小
	private int subSize = 50;
	
	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		//log.info("向微信支付平台发送充电预约退款请求,job start");
		List<OrderRefundStatus> list ;
		try{
			list = OrderRefundStatus.getRefundInfoForSend(OrderPayChannelCode.weixinpay.value());
			if(list != null && !list.isEmpty()){
				//截取一部分（50个）充电预约退款订单发送
				List<OrderRefundStatus> subList ;
				List<String> refundOrderNos ;
				if(list.size() >= subSize){
					subList = list.subList(0, subSize);
					refundOrderNos = new ArrayList<String>(subSize);
				} else {
					subList = list;
					refundOrderNos = new ArrayList<String>(list.size());
				}
				for(OrderRefundStatus crs : subList){
					refundOrderNos.add(crs.getOrderNo());
				}
				//修改充电预约退款订单的状态为"正在发送"
				OrderRefundStatus.changeStatusToSending(refundOrderNos);
				//找出充电预约退款订单列表
				List<OrderInfo> refundOrderList = OrderInfo.getByIds(refundOrderNos);
				//key为充电预约订单号，value为充电预约退款订单
				Map<String, OrderInfo> refundOrderMap = new HashMap<String, OrderInfo>();
				List<String> chargeAppointmentOrderNos = new ArrayList<String>();
				for(OrderInfo refundOrder : refundOrderList){
					//充电预约退款订单的关联订单为充电预约订单
					String chargeAppointmentOrderNo = refundOrder.getRelatedOrderNo();
					chargeAppointmentOrderNos.add(chargeAppointmentOrderNo);
					refundOrderMap.put(chargeAppointmentOrderNo, refundOrder);
				}
				//找出充电预约订单支付回调记录
				List<WeiXinPayCallBackRecord> weixinPayCallBackRecords = WeiXinPayCallBackRecord.getByIds(chargeAppointmentOrderNos);
				//要发送的参数
				Map<String, Object> paramMap = new TreeMap<String, Object>(
						new Comparator<String>(){
							@Override
							public int compare(String key1, String key2) {
								return key1.compareTo(key2);
							}
						}
				);
				List<String> needSendAgainOrderNos = new ArrayList<String>();
				List<String> successOrderNos = new ArrayList<String>();
				for(int i = 0 ; i < weixinPayCallBackRecords.size(); i++){
					WeiXinPayCallBackRecord weixinPayCallBackRecord = weixinPayCallBackRecords.get(i);
					String chargeAppointmentOrderNo = weixinPayCallBackRecord.getOrderNo();
					OrderInfo refundOrder = refundOrderMap.get(chargeAppointmentOrderNo);
					String refundOrderNo = refundOrder.getOrderNo();
					//公众账号ID
					paramMap.put("appid", weixinPayCallBackRecord.getAppId());
					//商户号
					paramMap.put("mch_id", weixinPayCallBackRecord.getPartnerNo());
					//设备号
					paramMap.put("device_info", weixinPayCallBackRecord.getDeviceInfo());
					//随机字符串
					paramMap.put("nonce_str", String.valueOf(UUIDUtil.longUUID()));
					//微信订单号
					paramMap.put("transaction_id", weixinPayCallBackRecord.getTradeNo());
					//paramMap.put("out_trade_no", chargeAppointmentOrderNo);
					//商户退款单号
					paramMap.put("out_refund_no", refundOrderNo);
					//总金额
					paramMap.put("total_fee", weixinPayCallBackRecord.getTotalFee());
					//退款金额,单位是分，所以需要乘以100
					BigDecimal refundFeeForSend = AmountUtil.multiply(refundOrder.getCaculatedTotalPrice(), new BigDecimal("100.00")).abs();
					paramMap.put("refund_fee", refundFeeForSend.toString());
					//货币种类
					paramMap.put("refund_fee_type", "CNY");
					//操作员帐号, 默认为商户号
					paramMap.put("op_user_id", weixinPayCallBackRecord.getPartnerNo());
					String sign = WeiXinPayUtil.sign(paramMap);
					paramMap.put("sign", sign);
					String paramXmlStr = XmlUtil.map2Xml(paramMap);
					String retXmlStrf = WeiXinPayUtil.sendRefundRequest(paramXmlStr);
					if(retXmlStrf == null || retXmlStrf.trim().length() == 0){
						needSendAgainOrderNos.add(refundOrderNo);
					} else {
						Map<String, Object> refundCallBackParams = XmlUtil.Xml2Map(retXmlStrf);
						String return_code = (String) refundCallBackParams.get("return_code");
						String result_code = (String) refundCallBackParams.get("result_code");
						//退款金额
						String refund_fee = (String) refundCallBackParams.get("refund_fee");
						if(!(return_code.equalsIgnoreCase(WeiXinPayUtil.RET_SUCCESS_STR) && result_code.equalsIgnoreCase(WeiXinPayUtil.RET_SUCCESS_STR))){
							log.error("向微信支付平台发送充电预约退款请求返回失败，refundOrderNo,return_code,result_code:", refundOrderNo + "," + return_code + "," + result_code);
							needSendAgainOrderNos.add(refundOrderNo);
						} else if(!AmountUtil.equal(new BigDecimal(refund_fee), refundFeeForSend)){
							log.error("向微信支付平台发送充电预约退款请求,返回的退款金额与发送的不符，refundOrderNo,refundFeeForSend,returnedRefundFee:", refundOrderNo + "," + refundFeeForSend + "," + refund_fee);
							needSendAgainOrderNos.add(refundOrderNo);
						} else {
							successOrderNos.add(refundOrderNo);
						}
					}
					WeiXinRefundReturnRecord weixinRefundCallBackRecord = WeiXinRefundReturnRecord.getBy(refundOrderNo);
					//查询订单退款回调记录是否存在
					if(weixinRefundCallBackRecord == null){
						//新增回调记录
						weixinRefundCallBackRecord = new WeiXinRefundReturnRecord(paramMap);
						weixinRefundCallBackRecord.save();
					} else {
						//更新回调记录
						weixinRefundCallBackRecord = new WeiXinRefundReturnRecord(paramMap);
						weixinRefundCallBackRecord.update();
					}
				}
				if(!needSendAgainOrderNos.isEmpty()){
					OrderRefundStatus.changeStatusToNeedSendAgain(needSendAgainOrderNos);
				}
				if(!successOrderNos.isEmpty()){
					OrderRefundStatus.changeStatusToSuccess(successOrderNos);
					OrderInfo.changeOrderStatus(successOrderNos, OrderStatus.payedDone.value());
					OrderAccountingStatus.batchSave(successOrderNos);
				}
			}
		} catch(Exception e){
			log.error("向微信支付平台发送充电预约退款请求出错", e);
		}
	}
}
